package org.lewis.man.controllers;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.lewis.common.domain.Tag;
import org.lewis.common.domain.User;
import org.lewis.common.service.TagService;
import org.lewis.common.service.UserService;
import org.lewis.common.store.OSSUtils;
import org.lewis.common.utils.ImageUtils;
import org.lewis.common.utils.WebUtils;

import com.tocersoft.framework.core.annotations.Controller;
import com.tocersoft.framework.core.annotations.Injection;
import com.tocersoft.framework.core.utils.PropertiesUtils;
import com.tocersoft.framework.web.HttpUtils;
import com.tocersoft.framework.web.annotations.Mapping;
import com.tocersoft.framework.web.annotations.NameSpace;
import com.tocersoft.framework.web.renderer.Renderer;
import com.tocersoft.framework.web.renderer.TemplateRenderer;
import com.tocersoft.framework.web.renderer.TextRenderer;

/**
 * 账户信息设置
 * 
 * @author taiqichao
 * 
 */
@Controller
@NameSpace("/accounts/settings")
public class AccountSettingsController{

	private final static String VIEW = "/WEB-INF/views/accounts/settings/";

	private final static int maxW = 200;
	private final static int maxH = 245;
	private final static int minWH = 48;
	private final static int miniWH = 24;

	Log log = LogFactory.getLog(AccountSettingsController.class);

	@Injection("userService")
	private UserService userService;

	@Injection
	private TagService tagService;

	/**
	 * 设置首页
	 * 
	 * @return
	 * @throws Exception
	 */
	@Mapping("/")
	public Renderer index() throws Exception {
		
		if(WebUtils.getCurrentUser()==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		
		return new TemplateRenderer(VIEW + "base_info.vm");
	}

	/**
	 * 基本信息
	 * 
	 * @return
	 * @throws Exception
	 */
	@Mapping("/baseinfo")
	public Renderer toBaseInfo() throws Exception {
		
		if(WebUtils.getCurrentUser()==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		Map<String, Object> data = new HashMap<String, Object>();
		if (WebUtils.isPost()) {
			String desc = WebUtils.getParameter("form_desc");
			User user = WebUtils.getCurrentUser();
			// 更新到数据库
			userService.updateUserDesc(user.getId(), WebUtils.safe(desc));
			user.setMydesc(WebUtils.safe(desc));
			// 更新session中用户信息
			WebUtils.modifyCurrentUser(user);
			data.put("msg", "success");
		}

		return new TemplateRenderer(VIEW + "base_info.vm",data);
	}

	/**
	 * 音乐标签
	 * 
	 * @return
	 * @throws Exception
	 */
	@Mapping("/tags")
	public Renderer toTagInfo() throws Exception {

		
		if(WebUtils.getCurrentUser()==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		if (WebUtils.isPost()) {
			String tags = WebUtils.getParameter("tags");
			if(StringUtils.isNotBlank(tags)){
				User user = WebUtils.getCurrentUser();
				user.setTags(tags);
				userService.updateUserTags(user.getId(), tags);
			}
			return new TextRenderer("success");
		}

		Map<String ,Object> data=new HashMap<String, Object>();
		data.put("tags0", tagService.queryByType(0));
		data.put("tags1", tagService.queryByType(1));
		data.put("tags2", tagService.queryByType(2));
		User user = WebUtils.getCurrentUser();
		
		//用户选中tags
		List<Tag> selectTags = tagService.getUserTags(user);
		
		data.put("selectedTagList", selectTags);
		return new TemplateRenderer(VIEW + "tags_info.vm", data);
	}

	/**
	 * 修改头像
	 * 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Mapping("/photo")
	public Renderer toPhotoInfo() throws Exception {
		
		
		User user = WebUtils.getCurrentUser();
		if(user==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		
		Map<String, Object> data = new HashMap<String, Object>();
		String photo = WebUtils.getCurrentUser().getMaxPhoto();
		data.put("photo", photo);
		
		if (WebUtils.isPost()) {// 处理文件上传
			String tempDir=PropertiesUtils.getValue("static.upload.tempdir")+"/"+UUID.randomUUID().toString();
			String absDir=WebUtils.getRealyPath(tempDir);
			File absDirs=new File(absDir);
			if(!absDirs.exists()){
				absDirs.mkdirs();
			}
			HttpServletRequest request = WebUtils.getRequest();
			int maxMemorySize = Integer.parseInt(PropertiesUtils
					.getValue("uploaded.maxMemorySize"));
			long maxRequestSize = Long.parseLong(PropertiesUtils
					.getValue("uploaded.maxFileSize"));
			String allowExt = PropertiesUtils.getValue("allow.image.ext");

			log.info("config:[maxMemorySize:" + maxMemorySize
					+ "] [maxRequestSize:" + maxRequestSize + "] [allowExt:"
					+ allowExt + "]");
			try {
				DiskFileItemFactory factory = new DiskFileItemFactory();
				factory.setSizeThreshold(maxMemorySize);
				ServletFileUpload upload = new ServletFileUpload(factory);
				upload.setSizeMax(maxRequestSize);
				List<FileItem> items = upload.parseRequest(request);
				FileItem item=null;
				for (FileItem ft : items) {
					if (!ft.isFormField()) {
						item=ft;
						break;
					}
				}
				if(item==null||(item!=null&&item.getSize()==0)){
					data.put("msg", "请选择一个文件");
					return new TemplateRenderer(VIEW+ "photo_info.vm", data);
				}
				
				// 格式校验
				String[] allowExts = allowExt.toLowerCase().split(",");
				String ext = StringUtils.substringAfterLast(
						item.getName(), ".").toLowerCase();
				if (!ArrayUtils.contains(allowExts, ext)) {
					log.debug("非法文件格式");
					data.put("msg", "非法文件格式");
					return new TemplateRenderer(VIEW+ "photo_info.vm", data);
				}
				
				// 上传后原图文件名
				String orginFileName = user.getId()+ "." + ext;
				// 小图文件名
				String smallFileName = user.getId()+ "_small" + ".jpg";
				//mini小图像
				String miniFileName = user.getId()+ "_mini" + ".jpg";
				
				// 相对路径
				String orginFilePath = tempDir + "/"+ orginFileName;
				String smallFilePath = tempDir + "/"+ smallFileName;
				String miniFilePath = tempDir + "/"+ miniFileName;
				
				// 生成文件
				File orginFile = new File(WebUtils.getRealyPath(orginFilePath));
				File smallFile = new File(WebUtils.getRealyPath(smallFilePath));
				File miniFile = new File(WebUtils.getRealyPath(miniFilePath));
				
				InputStream in = item.getInputStream();
				OutputStream out = new BufferedOutputStream(new FileOutputStream(orginFile), maxMemorySize);
				byte[] buffer = new byte[maxMemorySize];
				int length = 0;
				while ((length = in.read(buffer)) != -1) {
					out.write(buffer, 0, length);
				}
				IOUtils.closeQuietly(in);
				IOUtils.closeQuietly(out);

				// 对文件大小判断，看是否需要第一步缩放
				// 宽或者高大于最大,等比例缩放
				if (ImageUtils.getWidth(orginFile) > maxW|| ImageUtils.getHeight(orginFile) > maxH) {
					ImageUtils.resizeImage(orginFile, ext, orginFile,maxW, maxH, true);
				}
				// 宽或者高小于最小，放大
				if (ImageUtils.getWidth(orginFile) < minWH|| ImageUtils.getHeight(orginFile) < minWH) {
					ImageUtils.resizeImage(orginFile, ext, orginFile,minWH, minWH, false);
				}
				// 同时生成一张小图,和一张mini图
				ImageUtils.resizeImage(orginFile, ext, smallFile,minWH, minWH, false);
				ImageUtils.resizeImage(orginFile, ext, miniFile,miniWH, miniWH, false);
				
				//将本地文件上传至云服务器
				OSSUtils.storeUserFace(orginFile, orginFileName, user.getId());
				OSSUtils.storeUserFace(smallFile, smallFileName, user.getId());
				OSSUtils.storeUserFace(miniFile, miniFileName, user.getId());
				
				//删除本地文件
				FileUtils.deleteQuietly(orginFile);
				FileUtils.deleteQuietly(smallFile);
				FileUtils.deleteQuietly(miniFile);
				FileUtils.deleteDirectory(absDirs);
				
				// 更新用户头像信息
				user.setPhoto(orginFileName);
				WebUtils.modifyCurrentUser(user);
				userService.updateUserPhoto(user.getId(), user.getPhoto());
				WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+ "/accounts/settings/photo");
			} catch (Exception e) {
				data.put("msg", "文件过大,请不要上传超过4M的图片");
				new TemplateRenderer(VIEW + "photo_info.vm", data);
			}
		}
		
		return new TemplateRenderer(VIEW + "photo_info.vm", data);
	}

	@Mapping("/photo/cut/$1/$2/$3/$4")
	public Renderer doCutPhoto(int x, int y, int w, int h) throws Exception {
		
		User user = WebUtils.getCurrentUser();
		if(user==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		String photo = WebUtils.getCurrentUser().getPhoto();
		if (StringUtils.isEmpty(photo)) {
			return new TextRenderer("error");
		}
		if (x < 0 || y < 0 || w < 48 || h < 48) {
			return new TextRenderer("error");
		}
		
		String tempDir = PropertiesUtils.getValue("static.upload.tempdir")+ "/"+UUID.randomUUID().toString();
		File tempFileDir = new File(WebUtils.getRealyPath(tempDir));
		if (!tempFileDir.exists()) {
			tempFileDir.mkdirs();
		}
		
		//从云存储服务器上下载文件到本地
		String downloadPath=WebUtils.getRealyPath(tempDir+"/"+photo);
		File oginFile=new File(downloadPath);
		OSSUtils.getUserFace(photo, oginFile);
		
		// 原文件
		String ext = StringUtils.substringAfterLast(photo, ".").toLowerCase();
		// 切割后临时文件
		String tempfile = WebUtils.getRealyPath(tempDir + "/"+ UUID.randomUUID() + "." + ext);
		// 切图
		ImageUtils.cut(downloadPath, tempfile, x, y, w, h);
		
		// 缩放一张缩略图,和一张mini小图
		String smallFilePath = WebUtils.getRealyPath(tempDir+"/"+WebUtils.getCurrentUser().getSmallPhoto());
		String miniFilePath = WebUtils.getRealyPath(tempDir+"/"+WebUtils.getCurrentUser().getMiniPhoto());
		
		File smallFile = new File(smallFilePath);
		File miniFile = new File(miniFilePath);
		
		File tempFile = new File(tempfile);
		// 缩放
		ImageUtils.resizeImage(tempFile, ext, smallFile, minWH, minWH, false);
		ImageUtils.resizeImage(tempFile, ext, miniFile, miniWH, miniWH, false);
		
		String rm=StringUtils.substringBeforeLast(photo, ".")+"_small.jpg";
		String rmi=StringUtils.substringBeforeLast(photo, ".")+"_mini.jpg";
		
		//将新文件上传
		OSSUtils.storeUserFace(smallFile, rm, WebUtils.getCurrentUser().getId());
		OSSUtils.storeUserFace(miniFile, rmi, WebUtils.getCurrentUser().getId());
		
		// 删除临时文件
		FileUtils.deleteQuietly(tempFile);
		//删除下载的文件
		FileUtils.deleteQuietly(oginFile);
		//删除临时文件夹
		FileUtils.deleteDirectory(tempFileDir);
		
		return new TextRenderer("success");
	}

	/**
	 * 修改密码
	 * 
	 * @return
	 * @throws Exception
	 */
	@Mapping("/modifypwd")
	public Renderer modifyPassword() throws Exception {
		
		User user = WebUtils.getCurrentUser();
		if(user==null){
			WebUtils.getResponse().sendRedirect(HttpUtils.getContentPath()+"/accounts/login");
			return null;
		}
		
		Map<String, Object> data = new HashMap<String, Object>();
		if (WebUtils.isPost()) {
			String oldpwd = WebUtils.getParameter("old_password");
			String newpwd = WebUtils.getParameter("form_password");
			if (StringUtils.isEmpty(oldpwd) || StringUtils.isEmpty(newpwd)) {
				data.put("error_msg", "请将信息填写完整");
				return new TemplateRenderer(VIEW + "modify_password.vm", data);
			}

			if (!user.getPassword().equals(oldpwd)) {
				data.put("error_msg", "原始密码输入错误");
				return new TemplateRenderer(VIEW + "modify_password.vm", data);
			}

			// 更新session中密码
			user.setPassword(newpwd);
			WebUtils.modifyCurrentUser(user);
			// 更新到数据库
			userService.updateUserPassword(user.getId(), user.getPassword());
			data.put("success_msg", "密码修改成功");
		}

		return new TemplateRenderer(VIEW + "modify_password.vm", data);
	}

}
